package com.huawei.aiservice.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.huawei.aiservice.entity.pojo.FileEntity;
import com.huawei.aiservice.entity.pojo.FileRule;
import com.huawei.aiservice.entity.pojo.Report;
import com.huawei.aiservice.entity.pojo.Rule;
import com.huawei.aiservice.enums.ReportStatus;
import com.huawei.aiservice.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ScheduleServiceImpl implements ScheduleService {
    @Resource
    private ReportService reportService;

    @Resource
    private RuleService ruleService;

    @Resource
    private FileRuleService fileRuleService;

    @Resource
    private FileEntityService fileEntityService;
    @Override
    public void syncReportStatus() {
        LambdaQueryWrapper<Report> wrapper = Wrappers.<Report>lambdaQuery().eq(Report::getStatus, ReportStatus.PROCESSING);
        List<Report> reportList = reportService.list(wrapper);
        List<Rule> ruleList = ruleService.list();

        List<Report> updateList = new ArrayList<>();

        for (Report report : reportList) {

            boolean isTimeOut = checkTimeout(report);
            if (isTimeOut) {
                report.setStatus(ReportStatus.TIMEOUT);
                setFileRuleTimeout(report.getReportId());
                updateList.add(report);
                continue;
            }

            ReportStatus reportStatus = ReportStatus.SUCCESS;
            LambdaQueryWrapper<FileEntity> fileWrapper = Wrappers.<FileEntity>lambdaQuery().eq(FileEntity::getReportId, report.getReportId());
            List<FileEntity> fileEntityList = fileEntityService.list(fileWrapper);
            for (FileEntity fileEntity : fileEntityList) {
                for (Rule rule : ruleList) {
                    LambdaQueryWrapper<FileRule> fileRuleWrapper = Wrappers.<FileRule>lambdaQuery()
                            .eq(FileRule::getFileId, fileEntity.getFileId())
                            .eq(FileRule::getRuleId, rule.getRuleId());
                    FileRule fileRule = fileRuleService.getOne(fileRuleWrapper);
                    if (fileRule == null) {
                        reportStatus = ReportStatus.FAIL;
                        break;
                    }
                    if (!fileRule.getCheckStatus().equals(ReportStatus.SUCCESS)) {
                        reportStatus = ReportStatus.PROCESSING;
                        break;
                    }
                }
                // fail - reportfail
                if (reportStatus.equals(ReportStatus.PROCESSING) || reportStatus.equals(ReportStatus.FAIL)) {
                    break;
                }
            }
            if (!reportStatus.equals(ReportStatus.PROCESSING)) {
                report.setStatus(reportStatus);
                updateList.add(report);
            }
        }

        reportService.updateBatchById(updateList);
    }

    private void setFileRuleTimeout(int reportId) {
        LambdaQueryWrapper<FileEntity> wrapper = Wrappers.<FileEntity>lambdaQuery().eq(FileEntity::getReportId, reportId);
        List<FileEntity> fileEntityList = fileEntityService.list(wrapper);
        List<Integer> fileIds = fileEntityList.stream().map(FileEntity::getFileId).collect(Collectors.toList());

        LambdaQueryWrapper<FileRule> fileRuleWrapper = Wrappers.<FileRule>lambdaQuery().in(FileRule::getFileId, fileIds);
        List<FileRule> fileRuleList = fileRuleService.list(fileRuleWrapper);
        for (FileRule fileRule : fileRuleList) {
            fileRule.setCheckStatus(ReportStatus.TIMEOUT);
        }
        fileRuleService.updateBatchById(fileRuleList);
    }

    private boolean checkTimeout(Report report) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        try {
            // 解析目标时间
            Date targetDate = sdf.parse(report.getCreateTime());
            long createTime = targetDate.getTime();
            long now = System.currentTimeMillis();
            if (now - createTime > 60000*5) {
                return true;
            }
        } catch (ParseException e) {
            log.error("parse error", e);
            return true;
        }
        return false;
    }
}
